/* http_fetcher.h - HTTP handling functions

	HTTP Fetcher
	Copyright (C) 2001, 2003, 2004 Lyle Hanson (lhanson@users.sourceforge.net)

	This library is free software; you can redistribute it and/or
	modify it under the terms of the GNU Library General Public
	License as published by the Free Software Foundation; either
	version 2 of the License, or (at your option) any later version.

	This library is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
	Library General Public License for more details.

	See LICENSE file for details
									
 */

#ifndef HTTP_FETCHER_H
#define HTTP_FETCHER_H

class HttpFetcher {

/******************************************************************************/
/**************** Function declarations and descriptions **********************/
/******************************************************************************/

public:
	HttpFetcher();

/* 
 * [!!! NOTE !!!]  All HTTP Fetcher functions return -1 on error.  You can
 *	then either call http_perror to print the error message or call
 *	http_strerror to get a pointer to it
 */
		/*
		 * Download the url to localFile.
		 * Returns:
		 *	# of bytes downloaded, or
		 *	-1 on error
		 */
	int http_fetch(const char *url, HANDLE localFile, UINT& fileSize, UINT& downloadedSize, double limitSpeed);

		/*
		 * Returns a pointer to the current error description message.  The
		 *	message pointed to is only good until the next call to http_strerror(),
		 *	so if you need to hold on to the message for a while you should make
		 *	a copy of it.
		 */
	const char *http_strerror();


private:

/******************************************************************************/
/**** The following functions are used INTERNALLY by http_fetcher *************/
/******************************************************************************/

		/*
		 * Reads the metadata of an HTTP response.  On success returns the number
		 * Returns:
		 *	# of bytes read on success, or
		 *	-1 on error
		 */
	int _http_read_header(int sock, char *headerPtr);

		/*
		 * Opens a TCP socket and returns the descriptor
		 * Returns:
		 *	socket descriptor, or
		 *	-1 on error
		 */
	int makeSocket(const char *host);

		/*
		 * Determines if the given NULL-terminated buffer is large enough to
		 *	concatenate the given number of characters.  If not, it attempts to
		 *	grow the buffer to fit.
		 * Returns:
		 *	0 on success, or
		 *	-1 on error (original buffer is unchanged).
		 */
	int _checkBufSize(char **buf, int *bufsize, int more);

private:
	const char* DEFAULT_VERSION;
	const char* HTTP_VERSION;
	const char* DEFAULT_USER_AGENT;
	enum {  PORT_NUMBER = 80, 
			REQUEST_BUF_SIZE = 1024, 
			HEADER_BUF_SIZE = 1024, 
			DEFAULT_PAGE_BUF_SIZE = 1024*10, /* 10KB should hold most things */
			DEFAULT_REDIRECTS = 3,           /* Number of HTTP redirects to follow */
			DEFAULT_READ_TIMEOUT = 15};	     /* Seconds to wait before giving up
											  *	when no data is arriving */

	/* Error sources */
	enum {FETCHER_ERROR = 0, ERRNO = 1};

	/* HTTP Fetcher error codes */
	enum {  HF_SUCCESS = 0, HF_METAERROR = 1, HF_NULLURL = 2, HF_HEADTIMEOUT = 3, 
			HF_DATATIMEOUT = 4, HF_FRETURNCODE = 5, HF_CRETURNCODE = 6, 
			HF_STATUSCODE = 7, HF_CONTENTLEN = 8, HF_HERROR = 9, 
			HF_CANTREDIRECT = 10, HF_MAXREDIRECTS = 11};

private:
	const char *http_errlist[12];	/* Array of HTTP Fetcher error messages */

		/* Used to copy in messages from http_errlist[] and replace %d's with
		 *	the value of errorInt.  Then we can pass the pointer to THIS */
	char convertedError[128];
	int errorSource;
	int http_errno;
	int errorInt;			/* When the error message has a %d in it,
										*	this variable is inserted */
};

#endif
